/**
 * StkEnvelope
 * <p/>
 * User: joakimd
 * Date: 2013-03-11
 * Time: 15:47
 */
package org.dru.stk {
public final class StkEnvelope {
    private var _rates: Vector.<Number>;
    private var _levels: Vector.<Number>;
    private var _stage: Number;
    private var _current: Number;

    public function StkEnvelope() {
        _rates = new Vector.<Number>(5, true);
        _levels = new Vector.<Number>(6, true);
        _levels[1] = 1.0;
        reset();
        attack = 1.0;
        decay = 1.0;
        sustain = 1.0;
        release = 1.0;
    }

    public function set attack(value: Number): void {
        _rates[0] = value;
    }

    public function set decay(value: Number): void {
        _rates[1] = value;
    }

    public function set sustain(value: Number): void {
        _levels[2] = value;
        if (gate) {
            _levels[3] = value;
        }
    }

    public function set release(value: Number): void {
        _rates[3] = value;
    }

    public function get idle(): Boolean {
        return (_stage >= 4.0);
    }

    public function get gate(): Boolean {
        return (_stage < 3.0);
    }

    public function set gate(value: Boolean): void {
        if (value != gate) {
            if (value) {
                _levels[0] = current();
                _levels[3] = _levels[2];
                _stage = 0.0;
            }
            else {
                _levels[3] = current();
                _stage = 3.0;
            }
        }
    }

    public function reset(): void {
        _stage = 4.0;
        _current = 0.0;
    }

    public function current(): Number {
        return _current;
    }

    public function next(): Number {
        _stage += _rates[int(_stage)];
        const index: int = int(_stage);
        const tmp: Number = _levels[index];
        return _current = tmp + (_levels[index + 1] - tmp) * (_stage - Number(index));
    }
}
}
